import { Injectable } from '@nestjs/common';
import { Redis } from 'ioredis';
import { InjectRedis } from '@nestjs-modules/ioredis';

@Injectable()
export class RedisService {
    constructor(@InjectRedis() private readonly redis: Redis) { }

    // 根据key获取存储在Redis中的值  
    async get<T>(key: string): Promise<T | null> {
        const data = await this.redis.get(key);
        // 如果数据是字符串，则返回字符串，否则返回JSON解析后的对象
        if (typeof data === 'string') {
            return data as T;
        }
        return JSON.parse(data) as T;
    }

    // 设置Redis键值对，支持对象和基本类型
    async set(key: string, value: any, ttl?: number): Promise<void> {
        const stringValue = typeof value === 'string' ? value : JSON.stringify(value);
        if (ttl) {
            await this.redis.setex(key, ttl, stringValue);
        } else {
            await this.redis.set(key, stringValue);
        }
    }

    // 删除指定key的Redis数据
    async del(key: string): Promise<void> {
        await this.redis.del(key);
    }

    // 检查key是否存在
    async exists(key: string): Promise<boolean> {
        const result = await this.redis.exists(key);
        return result === 1;
    }

    // 设置key的过期时间
    async expire(key: string, ttl: number): Promise<void> {
        await this.redis.expire(key, ttl);
    }

    // 获取key的剩余过期时间
    async ttl(key: string): Promise<number> {
        return await this.redis.ttl(key);
    }

    // 批量获取多个key的值
    async mget<T>(keys: string[]): Promise<(T | null)[]> {
        const values = await this.redis.mget(keys);
        return values.map(value => value ? JSON.parse(value) : null);
    }

    // 批量设置多个key的值
    async mset(keyValues: { key: string; value: any; ttl?: number }[]): Promise<void> {
        const pipeline = this.redis.pipeline();
        for (const { key, value, ttl } of keyValues) {
            const stringValue = typeof value === 'string' ? value : JSON.stringify(value);
            if (ttl) {
                pipeline.setex(key, ttl, stringValue);
            } else {
                pipeline.set(key, stringValue);
            }
        }
        await pipeline.exec();
    }

    // 获取匹配模式的所有key
    async keys(pattern: string): Promise<string[]> {
        return await this.redis.keys(pattern);
    }

    // 清除匹配模式的所有key
    async clear(pattern: string): Promise<void> {
        const keys = await this.keys(pattern);
        if (keys.length > 0) {
            await this.redis.del(...keys);
        }
    }
}
